'use strict';

const Service = require('egg').Service;
const { randomNumber, prefixInteger } = require('../utils');
const {
  ORDER_TYPE,
  ORDER_STATE,
} = require('../constant/order');

class OrderService extends Service {

  async getOrderDetail({ orderId, userId }) {

    const query = { _id: orderId, user_id: userId };

    const o = await this.ctx.model.Order.findOne(query).lean();

    if (!o) {
      return [];
    }

    const queryOs = { order_id: orderId };

    const os = await this.ctx.model.OrderSubscription.findOne(queryOs).lean()

    const expertQuery = { _id: o.expert_id };

    const expertDetail = await this.ctx.model.Expert.findOne(expertQuery).lean()

    return [ o, expertDetail, os ];
  }


  getCountByQuery(query) {
    return this.ctx.model.Order.count(query).exec();
  }

  async getOrderList(query, option) {
    let list = await this.ctx.model.Order.find(
      query,
      [],
      option
    ).lean();

    if (!list || list.length === 0) {
      return [];
    }

    const fullList = await Promise.all(
      list.map(async (item) => {
        const queryOs = { order_id: item._id };

        const os = await this.ctx.model.OrderSubscription.findOne(queryOs).lean();
        if (os && os.chat_room_id) {
          item.chat_room_id = os.chat_room_id;
        }

        return item;
      })
    )

    return [ fullList ];
  }

  async getSubscriptionOrderDetailByQuery(query) {
    const os = await this.ctx.model.OrderSubscription.findOne(query).lean();
    if (!os) {
      return [];
    }

    return [ os ];
  }

  async getSubscriptionOrderDetail({ subscriptionOrderId, userId }) {
    const query = { _id: subscriptionOrderId, user_id: userId };

    const os = await this.ctx.model.OrderSubscription.findOne(query).lean();

    if (!os) {
      return [];
    }

    const expertQuery = { _id: os.expert_id };

    const expertDetail = await this.ctx.model.Expert.findOne(expertQuery).lean()

    const userQuery = { _id: os.user_id };

    const userDetail = await this.ctx.model.User.findOne(userQuery).lean();

    const orderQuery = { _id: os.order_id };

    const orderDetail = await this.ctx.model.Order.findOne(orderQuery).lean();

    return [ os, expertDetail, userDetail, orderDetail ];
  }

  getSubscriptionCountByQuery(query) {
    return this.ctx.model.OrderSubscription.count(query).exec();
  }

  async getSubscriptionOrderList(query, option) {
    const list = await this.ctx.model.OrderSubscription.find(
      query,
      [],
      option
    ).lean();
    
    if (list.length === 0) {
      return [];
    }

    const fullList = await Promise.all(
      list.map(async (item) => {
        const [ expert ] = await this.ctx.service.expert.getLightExpertDetail({
          expertId: item.expert_id,
        });
        if (expert) {
          item.expert = expert;
        }
        const orderQuery = { _id: item.order_id };
        const orderDetail = await this.ctx.model.Order.findOne(orderQuery).lean();
        if (orderDetail) {
          item.orderDetail = orderDetail;
        }
        return item;
      })
    )

    return [ fullList ];
  }

  async newOrder({
    userId,
    expertId,
    type,
    form = {},
  }) {
    const ctx = this.ctx;
    
    const {
      content,
      name,
      sex,
      age,
      phone,
      images,
      date,
      time,
    } = form;

    const expertQuery = { _id: expertId };
    const expertData = await this.ctx.model.Expert.findOne(expertQuery);

    let amountFee = 0;
    let productId = '';
    if (expertData.services) {
      expertData.services.map(item => {
        if (item.type === type) {
          amountFee = item.amount;
          productId = item.product_id;
        }
      });
    }

    // 生成订单号
    const code = randomNumber();
    
    // 创建order
    const o = new this.ctx.model.Order();

    o.code = code;
    o.order_type = ORDER_TYPE.ORDER_SUBSCRIPTION;
    o.order_biz_type = type,
    o.user_id = userId;
    o.expert_id = expertId;
    o.amount = amountFee;
    o.state = ORDER_STATE.NOPAY;

    o.save();
    
    // 创建order subscription
    const os = new this.ctx.model.OrderSubscription();

    os.order_id = o._id;
    os.type = type,
    os.code = code;
    os.name = name;
    os.content = content;
    os.sex = sex;
    os.age = age;
    os.phone = phone;
    os.images = images;
    os.expert_id = expertId;
    os.user_id = userId;
    os.date = date;
    os.time = time;
    

    


    const fromUser = {
      _id: userId,
    }
    
    const [ fromUserData ] = await ctx.service.user.getUser(fromUser);

    const toUser = {
      _id: expertData.user_id,
    }

    let [ toUserData ] = await ctx.service.user.getUser(toUser);

    
    if (!expertData.user_id || !toUserData) {
      const newToUser = new ctx.model.User();

      newToUser.name = expertData.name;

      let userSeq = await ctx.service.mongoCache.get('user_seq');
      userSeq = Number(userSeq || 0) + 1;

      await ctx.service.mongoCache.set('user_seq', userSeq);

      newToUser.code = prefixInteger(userSeq, 6);

      toUserData = {
        _id: newToUser._id,
      };

      await newToUser.save();
      expertData.user_id = newToUser._id.toString();
      await expertData.save();
    }


    const cm = new this.ctx.model.ChatRoom();
    cm.from_user_id = userId;
    cm.to_user_id = expertData.user_id;
    cm.state = 'OPEN';
    cm.save();

    os.chat_room_id = cm._id;
    os.save();
    

    const queryProduct = { type };
    const productOne = await ctx.model.Product.findOne(queryProduct)

    let messageId = null;
    if (productOne && productOne.has_chat_room) {
      messageId = await ctx.service.chat.newChatMessage(
        toUserData, fromUserData, content, cm._id
      );
    }

    return [ code, o, os, messageId ];
  }
}

module.exports = OrderService;
